from neutron import Plugin, execute, User
from fastapi.responses import StreamingResponse
import os
import aiofiles
from server import config
import sys
import asyncio
from . import user
from . import plugin

app = Plugin(__file__)

bg_cache: dict[str, str] = {}
bg_img_cache: dict[str, bytes] = {}


@app.route.post("/change_bg", level=1)
async def change_bg(user: User, css: str):
    if (user.demo):
        return {
            "code": 1,
            "msg": "演示模式下禁用本操作",
            "data": []
        }
    global bg_cache
    bg_cache[user.username] = css  # 将用户的背景css更新到bg_cache中
    # 从文件存储中加载用户的壁纸配置css文件
    bg_save = await app.filestorage.load(user, "wallpaper")
    async with bg_save.open(".css", "w") as file:
        await file.write(css)
    return css


@app.route.get("/get_bg")
async def get_bg(user: User):  # 获取用户背景css
    global bg_cache
    if (user.username not in bg_cache):
        bg_save = await app.filestorage.load(user, "wallpaper")
        if (not await bg_save.exists(".css")):
            return {"code": 1, "data": ""}  # 文件不存在返回空
        async with bg_save.open(".css", "r") as file:
            ret = await file.read()  # 读取文件内容
        bg_cache[user.username] = ret
        return {
            "code": 0,
            "data": ret
        }
    else:
        return {  # 返回缓存中的图片数据
            "code": 0,
            "data": bg_cache[user.username]
        }


@app.route.post("/change_bg_img", level=1)
async def change_bg_img(user: User, path: str):
    global bg_img_cache
    if (user.demo):
        return {
            "code": 1,
            "msg": "演示模式下禁用本操作",
            "data": []
        }
    if (not os.path.exists(path)):
        return {
            "code": 1,
            "msg": "文件不存在"
        }
    if (not os.path.isfile(path)):
        return {
            "code": 1,
            "msg": "不是一个文件"
        }
    if (os.stat(path).st_size > 1024*1024):  # 检查文件大小是否超过1MiB
        return {
            "code": 1,
            "msg": "文件大于 1 MiB"
        }
    async with aiofiles.open(path, "rb") as file:
        img = await file.read()
    bg_img_cache[user.username] = img  # 缓存
    # 从文件存储系统中加载用户的壁纸文件
    bg_save = await app.filestorage.load(user, "wallpaper")
    async with bg_save.open("wallpaper.png", "wb") as file:
        await file.write(img)
    return {
        "code": 0,
        "msg": ""
    }


@app.route.get("/bg_image/{any_str}")
async def get_bg_img(user: User, any_str: str = ""):
    global bg_img_cache
    if (user.username not in bg_img_cache):
        bg_save = await app.filestorage.load(user, "wallpaper")
        async with bg_save.open("wallpaper.png", "rb") as file:
            ret = await file.read()
        bg_img_cache[user.username] = ret
        return StreamingResponse(iter([ret]))  # 返回壁纸流
    else:
        return StreamingResponse(iter([bg_img_cache[user.username]]))  # 返回缓存


@app.route.post("/power")
async def power(user: User, power: str):  # 电源
    if (user.demo):
        return {
            "code": 1,
            "msg": "演示模式下禁用本操作"
        }
    if (not await app.checker.check_func_permission(user, 2, "power")):  # 检查用户是否有执行操作的权限
        return {
            "code": 1,
            "msg": "权限不足"
        }
    power_lst = {  # 电源操作列表
        "shutdown_sys": {
            "name": "服务器关机",
            "function": lambda: os.system("shutdown -P 60"),
            "info_msg": "服务器将在确认后 60 秒关机"
        },
        "reboot_sys": {
            "name": "服务器重启",
            "function": lambda: os.system("shutdown -r 60"),
            "info_msg": "服务器将在确认后 60 秒重启"
        },
        "cancel_sys": {
            "name": "取消电源操作",
            "function": lambda: os.system("shutdown -c"),
            "info_msg": "即将取消计划的电源操作"
        },
        "restart_panel": {
            "name": "重启面板",
            "function": lambda: os.execve(sys.executable, [sys.executable] + sys.argv, os.environ),
            "info_msg": "即将重启面板\n重启可能需要 1-3 分钟\n重启面板会停止当前的所有任务！"
        }
    }
    if (power not in power_lst):
        return {
            "code": 1,
            "msg": "无效的命令"
        }

    async def power_task(tools):
        await tools.write_log(power_lst[power]["info_msg"]+"\n")
        ret = await tools.show_buttons(["确认", "取消"])
        if (ret != 0):
            await tools.write_log("用户取消操作\n")
            await tools.exit(True)
        await asyncio.to_thread(power_lst[power]["function"])
        await tools.set_process(100)
        await tools.exit(False)
    await execute("tasks", "create_task")("电源", power_lst[power]["name"], power_task, user)
    return {
        "code": 0,
        "msg": ""
    }


@app.route.get("/show_tools")
async def show_tools(user: User):
    return {
        "code": 0,
        "msg": "",
        "data": {
            "power": await app.checker.check_func_permission(user, 2, "power"),
            "manager": await app.checker.check_func_permission(user, 2, "user"),
            "plugin": await app.checker.check_func_permission(user, 2, "plugin")
        }
    }


user.main(app)
plugin.main(app)
